#ifndef LIGHT_HPP
#define LIGHT_HPP

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/RenderTexture.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/Color.hpp>
#include <SFML/System/Vector2.hpp>

#include <SmegTools/Config.h>
#include <SmegCore/Entity/BaseEntity.hpp>

#include "../QuadTree/QuadTreeOccupant.hpp"

#include <SmegTools/Debug/DebugNew.hpp>

namespace smeg {
    namespace light {

////////////////////////////////////////////////////////////
/// Class representing a Light
////////////////////////////////////////////////////////////
class Light : public QuadTreeOccupant
{
public:
    ////////////////////////////////////////////////////////////
    /// Default Constructor
    ///
    /// \param _Color :     Color of the light
    /// \param _Center :    Center of the light
    /// \param _fAngleDeg : Rotation angle of the light
    /// \param _fAngleSpreadDeg : Cone of light (base is point light : 360 degrees)
    /// \param _fRadius :   Radius of the light
    /// \param _bIsStatic : Static of dynamic ?
    ///
    ////////////////////////////////////////////////////////////
                            Light( const sf::Color& _Color      = sf::Color::White, 
                                const sf::Vector2f& _Center     = sf::Vector2f(),
                                float _fAngleDeg                = 0.0f, 
                                float _fAngleSpreadDeg          = 360.0f, 
                                float _fRadius                  = 1.0f,
                                bool _bIsStatic                 = false );
    ////////////////////////////////////////////////////////////
    /// Copy Constructor
    ///
    /// \param _Copy :      Light to copy from
    ///
    ////////////////////////////////////////////////////////////
                            Light( const Light& _Copy );
    ////////////////////////////////////////////////////////////
    /// Destructor
    ///
    ////////////////////////////////////////////////////////////
    virtual                 ~Light();

    CREATE_CLONE_FUNC( Light, BaseEntity );
    
    ////////////////////////////////////////////////////////////
    /// Compute the static texture from the given texture
    ///
    /// \param _LightTexture : Texture to copyr into the static texture
    /// \param _pProjMatrix : Projection matrix
    ///
    ////////////////////////////////////////////////////////////
    void                    ComputeStatic( const sf::RenderTexture& _LightTexture, const float* _pProjMatrix );
    
    ////////////////////////////////////////////////////////////
    /// Render the static texture
    ///
    ////////////////////////////////////////////////////////////
    void                    RenderStatic() const;
    
    ////////////////////////////////////////////////////////////
    /// Is the point lit ?
    ///
    /// \param _Point :     Point to test
    ///
    /// \return Whether the given point is lit or not
    ///
    ////////////////////////////////////////////////////////////
    bool                    IsLit( const sf::Vector2f& _Point ) const;

    /*********************** Accessors ************************/
    void                    SetColor( const sf::Color& _Color );
    const sf::Color&        GetColor() const;
    
    void                    SetAngleSpreadRad( float _fAngleSpreadRad );
    void                    SetAngleSpreadDeg( float _fAngleSpreadDeg );
    float                   GetAngleSpreadRad() const;
    float                   GetAngleSpreadDeg() const;

    void                    SetRadius( float _fRadius );
    float                   GetRadius() const;

    float                   GetDotLit() const;

    sf::RenderTexture*      GetStaticTexture() const;

protected:
    friend class LightSystem;
                            
    ////////////////////////////////////////////////////////////
    /// Compute the AABB
    ///
    ////////////////////////////////////////////////////////////
    virtual void            ComputeAABB();

    /*********************** Accessors ************************/
    virtual void            SetStatic( bool _bIsStatic );

    /******************* Protected members ********************/
    sf::Color               m_Color;                /// Color of the light
    float                   m_fAngleSpread;         /// At how angle the light is spreading
    float                   m_fHalfAngleSpread;
    float                   m_fRadius;              /// How far the light will shine to
    float                   m_fDotLit;              /// Dot needed for a point to be lit

    sf::RenderTexture*      m_pStaticTexture;       /// Texture used for static lights

#ifdef _DEBUG
public:
    virtual void            SetAngleRad( float _fAngleRad );
    virtual void            RotateRad( float _fAngleRad );

    void                    DebugComputeVertices();
    void                    DebugRender( const sf::Color& _Color = sf::Color::White ) const;
    bool                    DEBUG_ShowInside;

protected:
    sf::Vector2f*           DEBUG_Vertices;             /// Vertices for rendering (to avoid too much computing when rendering)
#endif // _DEBUG
};

/************************** Inline ************************/
inline void Light::SetColor( const sf::Color& _Color ) {
    m_Color = _Color;
}

inline const sf::Color& Light::GetColor() const {
    return m_Color;
}

inline float Light::GetAngleSpreadRad() const {
    return m_fAngleSpread;
}

inline float Light::GetAngleSpreadDeg() const {
    return m_fAngleSpread * math::RAD_TO_DEG;
}

inline float Light::GetRadius() const {
    return m_fRadius;
}

inline float Light::GetDotLit() const {
    return m_fDotLit;
}

inline sf::RenderTexture* Light::GetStaticTexture() const {
    return m_pStaticTexture;
}

    } // namespace light
} // namespace smeg

#include <SmegTools/Debug/DebugNewOff.hpp>

#endif // LIGHT_HPP
